"""
SOP Domain Model
================

This module defines the SOP (Standard Operating Procedure) domain model
following Domain-Driven Design principles.
"""

from dataclasses import dataclass
from datetime import datetime
from typing import Optional


@dataclass
class SOP:
    """
    Standard Operating Procedure domain entity.
    
    Represents a standard operating procedure with subject, content,
    and metadata about creation.
    """
    id: Optional[int] = None
    subject: str = ""
    sop: str = ""
    created_at: Optional[datetime] = None
    created_by: str = ""
    
    def __post_init__(self):
        """Validate the SOP entity after initialization."""
        if not self.subject or not self.subject.strip():
            raise ValueError("Subject cannot be empty")
        if not self.sop or not self.sop.strip():
            raise ValueError("SOP content cannot be empty")
        if not self.created_by or not self.created_by.strip():
            raise ValueError("Created by cannot be empty")
        
        # Clean up string fields
        self.subject = self.subject.strip()
        self.sop = self.sop.strip()
        self.created_by = self.created_by.strip()
    
    def to_dict(self) -> dict:
        """Convert the SOP entity to a dictionary."""
        return {
            'id': self.id,
            'subject': self.subject,
            'sop': self.sop,
            'created_at': self.created_at.isoformat() if self.created_at else None,
            'created_by': self.created_by
        }
    
    @classmethod
    def from_dict(cls, data: dict) -> 'SOP':
        """Create a SOP entity from a dictionary."""
        created_at = None
        if data.get('created_at'):
            if isinstance(data['created_at'], str):
                created_at = datetime.fromisoformat(data['created_at'].replace('Z', '+00:00'))
            elif isinstance(data['created_at'], datetime):
                created_at = data['created_at']
        
        return cls(
            id=data.get('id'),
            subject=data.get('subject', ''),
            sop=data.get('sop', ''),
            created_at=created_at,
            created_by=data.get('created_by', '')
        )
    
    def __str__(self) -> str:
        """String representation of the SOP."""
        return f"SOP(id={self.id}, subject='{self.subject}', created_by='{self.created_by}')"
    
    def __repr__(self) -> str:
        """Detailed string representation of the SOP."""
        return (f"SOP(id={self.id}, subject='{self.subject}', "
                f"created_at={self.created_at}, created_by='{self.created_by}')")